package qq2564874169.tuaotuao.fx.orm;

import java.util.*;

public abstract class AbstractDbEntityCore implements DbEntityCore {
    private final static String rsKey = UUID.randomUUID().toString();
    private SqlCore core;

    public AbstractDbEntityCore(SqlCore core) {
        this.core = core;
    }

    protected ResetSpace createResetSpace() {
        return new DefaultResetSpace();
    }

    @Override
    public ResetSpace resetTable() {
        if (core.userdata().containsKey(rsKey) == false) {
            core.userdata().put(rsKey, createResetSpace());
        }
        return (ResetSpace) core.userdata().get(rsKey);
    }

    protected String getTableName(Class<?> table) {
        if (core.userdata().containsKey(rsKey)) {
            ResetSpace rs = (ResetSpace) core.userdata().get(rsKey);
            String name = rs.get(table);
            if (name != null) {
                return name;
            }
        }
        return DbEntity.get(table).getTableName();
    }

    private static class DefaultResetSpace implements ResetSpace {
        private List<Map<Class<?>, String>> maps = new ArrayList<>();

        @Override
        public void set(Class<?> clazz, Object... args) {
            String name = DbEntity.get(clazz).getTableName();
            for (int i = 0; i < args.length; i++) {
                name = name.replace("{" + i + "}", args[i].toString());
            }
            maps.get(0).put(clazz, name);
        }

        @Override
        public void newContext() {
            maps.add(0, new HashMap<>(4));
        }

        @Override
        public String get(Class<?> clazz) {
            String name = null;
            for (Map<Class<?>, String> map : maps) {
                name = map.getOrDefault(clazz, null);
                if (name != null) {
                    break;
                }
            }
            return name;
        }

        @Override
        public void close() {
            if (maps.size() > 0) {
                maps.get(0).clear();
                maps.remove(0);
            }
        }
    }
}
